package cn.tqfeiyang.smartadmin.commons.security;

import cn.tqfeiyang.smartadmin.commons.mybatis.IEntityCache;
import cn.tqfeiyang.smartadmin.commons.toolbox.BeanUtils;
import cn.tqfeiyang.smartadmin.system.entity.UserEntity;
import cn.tqfeiyang.smartadmin.system.mapper.UserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Objects;

/**
 * JDBC用户加载器
 *
 * @author tqfeiyang
 * @since 2024/10/16 11:46
 */
@Service
@Slf4j
public class JdbcUserLoader implements IUserLoader, IEntityCache<UserDetails> {

    /**
     * 用户详情缓存
     */
    private static final String USER_DETAILS_CACHE = "system:security:userDetails";

    /**
     * 用户映射接口
     */
    @Resource
    private UserMapper userMapper;

    /**
     * 根据用户账号查找用户详情
     *
     * @param username 用户账号、也可以是电子邮件或者手机号
     * @return 用户详情，如果找不到则返回null
     */
    @Override
    public UserDetails findUserDetails(String username) {
        Assert.notNull(username, "username不能为空");
        LambdaQueryWrapper<UserEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.or().eq(UserEntity::getUsername, username);
        wrapper.or().eq(UserEntity::getEmail, username);
        wrapper.or().eq(UserEntity::getPhone, username);
        UserEntity userEntity = userMapper.selectOne(wrapper);
        return Objects.nonNull(userEntity) ? createUserDetails(userEntity) : null;
    }

    /**
     * 根据用户id查找用户详情
     *
     * @param userId 用户id
     * @return 用户详情，如果找不到则返回null
     */
    @Override
    @Cacheable(USER_DETAILS_CACHE)
    public UserDetails findUserDetails(Long userId) {
        Assert.notNull(userId, "userId不能为空");
        UserEntity userEntity = userMapper.selectById(userId);
        return Objects.nonNull(userEntity) ? createUserDetails(userEntity) : null;
    }

    /**
     * 根据用户实体对象创建用户详情对象
     *
     * @param userEntity 实体对象
     * @return 用户详情
     */
    private UserDetails createUserDetails(UserEntity userEntity) {
        UserDetails userDetails = new UserDetails();
        BeanUtils.copyProperties(userEntity, userDetails);
        return userDetails;
    }

    /**
     * 清理缓存
     */
    @Override
    @CacheEvict(value = USER_DETAILS_CACHE,
            allEntries = true)
    public void clearCache() {
        log.info("清空用户详情缓存");
    }
}
